/*
 *  Copyright 2011 derek.
 * 
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package com.aocore.packet.GS;

import com.aocore.d2data.NPCCode;
import com.aocore.packet.GSPacket;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

/**
 *
 * @author derek
 */
//http://www.assembla.com/code/aobot/subversion/nodes/trunk/Awesom-O/NpcReader.h
public class AssignNPC extends GSPacket
{
    protected int uid;
    protected NPCCode id;
    protected int x;
    protected int y;
    protected byte life;

    public AssignNPC(byte... data)
    {
        super(data);

        ByteBuffer byteBuffer = ByteBuffer.wrap(data);
        byteBuffer.order(ByteOrder.LITTLE_ENDIAN); 
        this.uid = byteBuffer.getInt(1);
        this.id = NPCCode.valueOf(byteBuffer.getShort(5));
        this.x = byteBuffer.getShort(7);
        this.y = byteBuffer.getShort(9);
        this.life = data[11];
        if (this.life < 0) this.life ^= 0xFF; // make it positive
        //data[12] = packet length
        
        
/*
        static NPC NewMonster(const BYTE * data, size_t size, unsigned char difficulty)                 
        {
                ////////////////////////////////////////////////////////////
                //thx to TheUnkownSoldier @ EON for the complete structure//
                ////////////////////////////////////////////////////////////
                unsigned int PacketSize;
                NPC npc;
                unsigned int r = 0;

                BitsReader br(data,size);
                br.read(8);

                npc.uid = br.read(32);
                npc.id = (NPCCode::NPCCode)br.read(16);
                npc.x = br.read(16);
                npc.y = br.read(16);
                npc.life = br.read(8);
                if(npc.life < 0) npc.life_percent = npc.life ^ 0xFF; // make it positive
                npc.life_percent = static_cast<unsigned char>((static_cast<float>(npc.life_percent))/128*100);

                PacketSize = br.read(8);
                short MonAnim = br.read(4);

                ResistInfo resist;
                monInfo.getMonsterResist(npc.id,&resist);
                memcpy(npc.res,&resist.res[difficulty], sizeof(resist.res[difficulty]));

                r = br.read(1);         

                if (r)
                {
                        int id = npc.id;

                        switch(id)
                        {
                                case NPCCode::UberMephisto: id = 604; break;
                                case NPCCode::Lilith: id = 605; break;
                                case NPCCode::UberIzual: id = 606; break;
                                case NPCCode::UberDuriel: id = 607; break;
                                case NPCCode::UberBaal: id = 608; break;
                        }
                        if (id > 608)
                                return npc;

                        BYTE gfxTypeInfo[NPC_GFX_TYPE_NUM];
                        monInfo.getGfxTypeInfo(id, gfxTypeInfo); 

                        int bits = 0;
                        for (size_t i = 0; i < NPC_GFX_TYPE_NUM; i++)
                        {
                                if (gfxTypeInfo[i] > 2 && gfxTypeInfo[i] < 10 )
                                        bits += bsr(gfxTypeInfo[i] - 1) + 1;
                                else
                                        bits += 1;
                        }
                        br.read(bits);
                }

                r = br.read(1);         

                if (r) //Monster mods
                {
                        npc.hero = (bool)br.read(1);    
                        npc.unique = (bool)br.read(1);
                        npc.superunique = (bool)br.read(1);
                        npc.minion = (bool)br.read(1);
                        npc.ghostly = (bool)br.read(1);
                        if (npc.superunique)
                                npc.uniqueid = (SuperUnique::SuperUnique)br.read(16);

                        for (int i = 0; i <= 10; i++)
                        {
                                short result = br.read(8);
                                if(result == 0)
                                        break;
                                npc.mods.push_back((MonsterMod::MonsterMod) result);
                                switch((MonsterMod::MonsterMod) result)
                                {                       
                                        case MonsterMod::cold:
                                        {
                                                npc.res[ResistType::Cold] += 75;                                        
                                        }
                                        break;
                                        case MonsterMod::fire:
                                        {
                                                npc.res[ResistType::Fire] += 75;
                                        }
                                        break;
                                        case MonsterMod::light:
                                        {
                                                npc.res[ResistType::Lightning] += 75;
                                        }
                                        break;
                                        case MonsterMod::resist:
                                        {
                                                npc.res[ResistType::Lightning] += 40;
                                                npc.res[ResistType::Fire] += 40;
                                                npc.res[ResistType::Cold] += 40;
                                        }
                                        break;
                                        case MonsterMod::manahit:
                                        {
                                                npc.res[ResistType::Magic] += 20;
                                        }
                                        break;
                                        case MonsterMod::spectralhit:
                                        {
                                                npc.res[ResistType::Lightning] += 20;
                                                npc.res[ResistType::Fire] += 20;
                                                npc.res[ResistType::Cold] += 20;
                                        }
                                        case MonsterMod::stoneskin:
                                        {
                                                npc.res[ResistType::Damage] += 50;                              
                                        }
                                        break;
                                }
                        }
                        short MonNameIndex = br.read(16);

                        npc.hasowner = br.read(1);
                        if (npc.hasowner)
                                npc.owner = br.read(32);

                }
                
                npc.isPet = br.read(1);
                if (npc.isPet)
                        npc.petowner = br.read(32);

                //nbytes of stats left, cba.
                
                return npc;
        }
*/
    }

    public int getUid()
    {
        return uid;
    }

    public NPCCode getId()
    {
        return id;
    }

    public int getX()
    {
        return x;
    }

    public int getY()
    {
        return y;
    }

    public byte getLife()
    {
        return life;
    }

    @Override
    public String toString()
    {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("GSPacket: ").append("AssignNPC").append("\n");
        stringBuilder.append("uid: ").append(uid).append("\n");
        stringBuilder.append("id: ").append(id).append("\n");
        stringBuilder.append("x: ").append(x).append("\n");
        stringBuilder.append("y: ").append(y).append("\n");
        stringBuilder.append("life: ").append(life).append("\n");
        return stringBuilder.toString();
    }
}
